﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using Microsoft.Research.DynamicDataDisplay.DirectX2D;
using Microsoft.Research.DynamicDataDisplay;
using Microsoft.Research.DynamicDataDisplay.DataSources;
using Microsoft.Research.DynamicDataDisplay.Charts.Navigation;
using Microsoft.Research.DynamicDataDisplay.ViewportRestrictions;
using Microsoft.Research.DynamicDataDisplay.Charts;
using Microsoft.Research.DynamicDataDisplay.Common.Auxiliary;
using Microsoft.Research.DynamicDataDisplay.Common;
using System.Data.OleDb;
using System.Data;
using System.Diagnostics;
using System.IO;


namespace TestD3DirectX
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {

        private DataTable dataPointsDataTable;

        private List<ChartPlotter> plotterList = new List<ChartPlotter>();
        //private List<WPFWaveFormViewer.D3Customization.LineGraph> lineGraphs = new List<WPFWaveFormViewer.D3Customization.LineGraph>();
        private List<ViewportElement2D> lineGraphs = new List<ViewportElement2D>();

        List<SeriesToAdd> listSeriesToAdd = new List<SeriesToAdd>();

        List<string> seriesList = new List<string>();
        int seriesNameColumnIndex = 0, bindAxisColumnIndex = 0, plotterColumnIndex = 0;

        private SlimDXControl slimDXControl = new SlimDXControl();


        public Window1()
        {
            InitializeComponent();
            //RemoveStdContextMenuAndAddCustomMenu(this.plotter1);
            // Add SlimDXControl
            this.plotter1.Children.Add(slimDXControl);

        }


        void RemoveStdContextMenuAndAddCustomMenu(ChartPlotter plotter)
        {
            plotter.DefaultContextMenu.RemoveFromPlotter();
            plotter.Children.Remove(plotter.DefaultContextMenu);
            plotter.Children.Remove(plotter.KeyboardNavigation);

            //plotter.AddHandler(UIElement.MouseRightButtonDownEvent, (RoutedEventHandler)ChartPlotter_MouseRightButtonDown);

        }

        DirectXLineGraph lineGraph = null;
        //LineGraph lineGraph = null;

        private void Window_Loaded(object sender, RoutedEventArgs e)
        {

        }


      

        #region Data operations
        void LoadData()
        {

            string txtFilePath = System.IO.Directory.GetCurrentDirectory() + @"\Data\Data.xls";
            System.Data.OleDb.OleDbConnection excelConnection = null;
            string sql = "";
            sql = "select * from [PLOTTER$]";
            excelConnection = new System.Data.OleDb.OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + txtFilePath + ";Extended Properties=\"Excel 8.0;HDR=YES;\"");
            excelConnection.Open();
            DataSet ds = new DataSet();
            System.Data.OleDb.OleDbDataAdapter da = new System.Data.OleDb.OleDbDataAdapter(sql, excelConnection);
            da.Fill(ds);
            dataPointsDataTable = ds.Tables[0];
        }

        IPointDataSource LoadSeries(IPointDataSource xAxisDataSource, string seriesName)
        {
            EnumerableDataSource<double> points = GetYDataSource(seriesName);
            IPointDataSource pointDS = xAxisDataSource.Join(points);
            return pointDS;
        }

        EnumerableDataSource<double> GetDataSource(string columnName)
        {
            double[] xPoints = new double[dataPointsDataTable.Rows.Count];
            for (int i = 0; i < dataPointsDataTable.Rows.Count; i++)
            {
                xPoints[i] = Convert.ToDouble(dataPointsDataTable.Rows[i][columnName]);
            }
            return xPoints.AsDataSource();
        }

        EnumerableDataSource<double> GetXDataSource(string columnName)
        {
            double[] xPoints = new double[dataPointsDataTable.Rows.Count];
            for (int i = 0; i < dataPointsDataTable.Rows.Count; i++)
            {
                xPoints[i] = Convert.ToDouble(dataPointsDataTable.Rows[i][columnName]);
            }
            return xPoints.AsXDataSource();
        }

        EnumerableDataSource<double> GetYDataSource(string columnName)
        {
            double[] xPoints = new double[dataPointsDataTable.Rows.Count];
            for (int i = 0; i < dataPointsDataTable.Rows.Count; i++)
            {
                xPoints[i] = Convert.ToDouble(dataPointsDataTable.Rows[i][columnName]);
            }
            return xPoints.AsYDataSource();
        }
        void StartToLoadData()
        {


            LoadData();

            string xAxisSeriesName = dataPointsDataTable.Columns[0].ColumnName;

            EnumerableDataSource<double> xAxisDataSource = null;
            xAxisDataSource = GetXDataSource(xAxisSeriesName);


            foreach (DataColumn column in dataPointsDataTable.Columns)
            {
                switch (column.ColumnName)
                {
                    case "SeriesName":
                        seriesNameColumnIndex = dataPointsDataTable.Columns.IndexOf(column);
                        break;
                    case "Yaxis":
                        bindAxisColumnIndex = dataPointsDataTable.Columns.IndexOf(column);
                        break;
                    case "Plotter":
                        plotterColumnIndex = dataPointsDataTable.Columns.IndexOf(column);
                        break;
                    default:
                        if (column.ColumnName != "F" + (dataPointsDataTable.Columns.IndexOf(column) + 1))
                        {
                            //seriesList.Add(column.ColumnName);_writer.Write
                        }
                        else
                        {

                        }
                        break;

                }

            }

            foreach (DataRow dr in dataPointsDataTable.Rows)
            {
                if (dr[seriesNameColumnIndex] != DBNull.Value)
                {
                    seriesList.Add(Convert.ToString(dr[seriesNameColumnIndex]));

                }
            }

            foreach (string series in seriesList)
            {
                foreach (DataRow dr in dataPointsDataTable.Rows)
                {
                    if (dr[seriesNameColumnIndex] != DBNull.Value)
                    {
                        if ((string)dr[seriesNameColumnIndex] == series)
                        {
                            ChartPlotter plotter = plotter1;

                            bool bindToLeftAxis = true;
                            IPointDataSource dataSource = LoadSeries(xAxisDataSource, series);

                            listSeriesToAdd.Add(new SeriesToAdd(plotter, dataSource, series, bindToLeftAxis));
                            //lineGraphs.Add(AddSeries(plotter, dataSource, series, bindToLeftAxis));
                        }
                    }
                }
            }

            //AddLineSeriesToD3();
            AddLineSeriesToD3DirectX();

        }

        void AddLineSeriesToD3DirectX()
        {


            foreach (SeriesToAdd seriesToAdd in listSeriesToAdd)
            {
                bool containsSlimDXControl = false;
                foreach (IPlotterElement element in seriesToAdd.plotter.Children)
                {
                    if (element is Microsoft.Research.DynamicDataDisplay.DirectX2D.SlimDXControl)
                    {
                        containsSlimDXControl = true;
                        break;
                    }
                }
                if (!containsSlimDXControl)
                {
                    //seriesToAdd.plotter.Children.Add(new Microsoft.Research.DynamicDataDisplay.DirectX2D.SlimDXControl());
                }


                DirectXLineGraph lineGraph = AddSeriesToD3DX(seriesToAdd.plotter, seriesToAdd.dataSource,
                    seriesToAdd.legend, seriesToAdd.bindToRightAxis);


                lineGraphs.Add(lineGraph);
            }

        }

        DirectXLineGraph AddSeriesToD3DX(ChartPlotter plotter, IPointDataSource dataSource, string legendName, bool bindToLeftAxis)
        {

            ////return  new WPFWaveFormViewer.D3Customization.LineGraph(
            ////                            plotter.AddLineGraph(dataSource, 1, legendName), plotter);



            //DirectXLineGraph lineGraph = null;
            //if (bindToLeftAxis)
            //{

            //    lineGraph = plotter.AddDXLineGraph(dataSource, Colors.Blue, 1, legendName);
            //    lineGraph.ProvideVisiblePoints = false;



            //}

            DirectXLineGraph lineGraph = null;
            double[] yPts = new double[] { 11, 44, 22, 55, 33, 88, 66, 77, 99, 110 };
            double[] xPts = new double[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

            IPointDataSource dSource = xPts.AsXDataSource().Join(yPts.AsYDataSource());
            lineGraph = plotter.AddDXLineGraph(dSource, Colors.Blue, 1, legendName);








            return lineGraph;
        }

        #endregion

        private void radButton_Checked(object sender, RoutedEventArgs e)
        {
            int noPts = 5000;
            if (((RadioButton)sender).Name == "rad10K")
            {
                noPts = 10000;
            }
            else if (((RadioButton)sender).Name == "rad20K")
            {
                noPts = 20000;
            }
            else if (((RadioButton)sender).Name == "rad30K")
            {
                noPts = 30000;
            }
            else if (((RadioButton)sender).Name == "rad50K")
            {
                noPts = 50000;
            }
            else if (((RadioButton)sender).Name == "rad100K")
            {
                noPts = 100000;
            }
            
            double[] yPts = new double[noPts];
            double[] xPts = new double[noPts];

            double start = this.startNumerator / (double)noPts;
            Random random = new Random();

            for (int i = 0; i < noPts; i++)
            {
                xPts[i] = i * start;
                if (i > noPts / 3 && i < noPts * 2 / 3)
                {
                    yPts[i] = random.Next(500) / 1000.0;
                }
                else
                {
                    yPts[i] = random.Next(1000) / 100.0;
                }
                //yPts[i] = random.Next(1000) / 1000.0;
            }
            if (lineGraph != null)
            {
                IPointDataSource dSource = xPts.AsXDataSource().Join(yPts.AsYDataSource());
                lineGraph.DataSource = dSource;
                
                slimDXControl.ForceRendering();
            }
        }

        double startNumerator = 10;

        private void Window_ContentRendered(object sender, EventArgs e)
        {
            //DirectXLineGraph lineGraph = null;
            //double[] yPts = new double[] { 11, 44, 22, 55, 33, 88, 66, 77, 99, 110 };
            //double[] xPts = new double[] { 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 };

            //IPointDataSource dSource = xPts.AsXDataSource().Join(yPts.AsYDataSource());
            //lineGraph = plotter1.AddDXLineGraph(dSource, Colors.Blue, 1, "Phase");

            //plotter1

            //StartToLoadData();


            int noPts = 10000;
            double[] yPts = new double[noPts];// { .11, .44, .22, .55, .33, .88, .66, .77, .99, 1.10 };
            double[] xPts = new double[noPts];// { 10, 20, 30, 40, 50, 60, 70, 80, 90, 100 };

            double start = this.startNumerator / (double)noPts;
            Random random = new Random();

            for (int i = 0; i < noPts; i++)
            {
                xPts[i] = i * start;

                if (i > noPts / 3 && i < noPts * 2 / 3)
                {
                    yPts[i] = random.Next(500) / 1000.0;
                }
                else
                {
                    yPts[i] = random.Next(1000) / 100.0;
                }
            }
            IPointDataSource dSource = xPts.AsXDataSource().Join(yPts.AsYDataSource());
            lineGraph = plotter1.AddDXLineGraph(dSource, Colors.Blue, 1, "Phase");

            //lineGraph = plotter1.AddLineGraph(dSource, Colors.Blue, 1, "Phase");
            lineGraph.Filters.Clear();
            lineGraph.Filters.Add(new Microsoft.Research.DynamicDataDisplay.Filters.FrequencyFilter());
        }
    }
}
